package com.tds.springbootdemo2.util;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * Copyright (C) 2014-2016 天津紫藤科技有限公司. Co. Ltd. All Rights Reserved.
 *
 * @author Andy
 * @version v1
 * @description 字符串工具类
 * @utill
 * @module
 * @date 2016年11月25日
 * @code
 */
@Slf4j
public class SignTools {
    /**
     * 返回一个升序排序的树map
     *
     * @return
     */
    public static Map<String, Object> getTreeMap() {
        return new TreeMap<>(Comparator.naturalOrder());
    }

    /**
     * map转换为字符串
     *
     * @param map
     * @return
     */
    public static String getParamStr(Map<String, Object> map) {
        StringBuilder returnStr = new StringBuilder();
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            returnStr.append(key).append("=").append(map.get(key)).append("&");
        }
        returnStr.deleteCharAt(returnStr.length() - 1);
        return returnStr.toString();
    }

    public static String convertMapToStr(Map<String, Object> map) {
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        List<String> list = new ArrayList<>();
        for (Map.Entry<String, Object> next : entries) {
            String key = next.getKey();
            Object value = next.getValue();
            if (value != null && !StrUtil.isBlank(String.valueOf(value))) {
                list.add(key + "=" + value);
            }
        }
        log.info("[签名字符串：{}]", list.toString());
        return String.join("&", list);
    }

    /**
     * MD5加密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static String encryptMD5(String data) throws Exception {

        String reStr = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(data.getBytes());
            StringBuilder stringBuffer = new StringBuilder();
            for (byte b : bytes) {
                int bt = b & 0xff;
                if (bt < 16) {
                    stringBuffer.append(0);
                }
                stringBuffer.append(Integer.toHexString(bt));
            }
            reStr = stringBuffer.toString().toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            log.error(e.getMessage(), e);
        }
        return reStr;
    }

    /**
     * 加密map形式的data
     * @param map
     * @return
     * @throws Exception
     */
    public static String encryptMapMD5(Map<String, Object> map) throws Exception{
        return encryptMD5(getParamStr(map));
    }

    /**
     * UTF8加密map形式的data
     * @param map
     * @return
     * @throws Exception
     */
    public static String utf8EncryptMapMD5(Map<String, Object> map) throws Exception{
        return encoderByMD5(getParamStr(map));
    }

    public static String utf8EncryptMapToMD5WithoutNullValue(Map<String, Object> map) throws Exception {
        return encoderByMD5(convertMapToStr(map));
    }
    public static String utf8EncryptMapToMD5WithoutNullValueDR(Map<String, Object> map) throws Exception {
        return encoderByMD5DR(convertMapToStr(map));
    }

    /**
     * utf8MD5加密
     * @param str
     * @return
     * @throws Exception
     */
    public static String encoderByMD5(String str)  throws Exception {
        String result = "";
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            // 这句是关键
            md5.update(str.getBytes(StandardCharsets.UTF_8));
        } catch (NoSuchAlgorithmException e) {
            log.error(e.getMessage(), e);
        }
        byte[] b = Objects.requireNonNull(md5).digest();
        int i;
        StringBuilder buf = new StringBuilder("");
        for (byte b1 : b) {
            i = b1;
            if (i < 0) {
                i += 256;
            }
            if (i < 16) {
                buf.append("0");
            }
            buf.append(Integer.toHexString(i));
        }
        result = buf.toString();

        return result;
    }


    public static String encoderByMD5DR(String str)  throws Exception {
        String result = "";
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            // 这句是关键
            md5.update(str.getBytes(StandardCharsets.UTF_8));
        } catch (NoSuchAlgorithmException e) {
            log.error(e.getMessage(), e);
        }
        byte[] b = Objects.requireNonNull(md5).digest();
        int i;
        StringBuilder buf = new StringBuilder("");
        for (byte b1 : b) {

            buf.append(String.format("%02x",b1));
        }
        result = buf.toString();

        return result;
    }

//    public static void main(String[] args) throws Exception {
//        //加密内容
//        final String content = "hello hello hello";
//        /*
//         * 单向加密 md5 & sha
//         */
//        //md5 加密
//        MessageDigest md5 = MessageDigest.getInstance("md5");
//        byte[] md5SecretStr = md5.digest(content.getBytes());
//        System.out.print("md5 加密 : { " + new String(shaded.org.apache.commons.codec.binary.Base64.encodeBase64(md5SecretStr)) + " }\n\r");
//
//        //sha 加密
//        MessageDigest sha = MessageDigest.getInstance("sha");
//        byte[] shaSecretBytes = sha.digest(content.getBytes());
//        System.out.print("sha 加密 : { " + new String(shaded.org.apache.commons.codec.binary.Base64.encodeBase64(shaSecretBytes)) + " }\n\r");
//
//        /*
//         * 对称加密 aes & des
//         */
//        //aes 加密
//        KeyGenerator aesKeyGenerator = KeyGenerator.getInstance("aes");
//        SecretKey aesSecretKey = aesKeyGenerator.generateKey();
//        Cipher aesCipher = Cipher.getInstance("aes");
//        aesCipher.init(Cipher.ENCRYPT_MODE, aesSecretKey);
//        byte[] aseResultBytes = aesCipher.doFinal(content.getBytes());
//        System.out.print("aes 加密 : { " + new String(shaded.org.apache.commons.codec.binary.Base64.encodeBase64(aseResultBytes)) + " }\n\r");
//
//        //aes 解密
//        aesCipher.init(Cipher.DECRYPT_MODE, aesSecretKey);
//        aseResultBytes = aesCipher.doFinal(aseResultBytes);
//        System.out.print("aes 解密: { " + new String(aseResultBytes) + " }\n\r");
//
//
//        //des 加密
//        KeyGenerator desKeyGenerator = KeyGenerator.getInstance("aes");
//        SecretKey desSecretKey = desKeyGenerator.generateKey();
//        Cipher desCipher = Cipher.getInstance("aes");
//        desCipher.init(Cipher.ENCRYPT_MODE, desSecretKey);
//        byte[] dseResultBytes = desCipher.doFinal(content.getBytes());
//        System.out.print("des 加密 : { " + new String(shaded.org.apache.commons.codec.binary.Base64.encodeBase64(dseResultBytes)) + " }\n\r");
//
//        desCipher.init(Cipher.DECRYPT_MODE, desSecretKey);
//        dseResultBytes = desCipher.doFinal(dseResultBytes);
//        System.out.print("aes 解密: { " + new String(dseResultBytes) + " }\n\r");
//
//    }

}
